import copy


from cookielib import LWPCookieJar
from urllib import urlencode
from urllib2 import urlopen, build_opener, install_opener
from urllib2 import Request, URLError
from urllib2 import HTTPCookieProcessor
from HTMLParser import HTMLParser

from constants import COOKIEFILE

class AbstractParser (HTMLParser):


    def __init__ (self,url=None,premium = False,handle = None):

        HTMLParser.__init__(self)
        self.premium = premium
        cj = LWPCookieJar()
        cj.load(COOKIEFILE)
        
        if handle is None:
            try:
                if self.premium:
                #cookies support
                    opener = build_opener \
                        (HTTPCookieProcessor(cj))
                    install_opener(opener)
                    self.urlHandler = opener.open(url)
                    cj.save(COOKIEFILE)
                else:
                    self.urlHandler = urlopen(url)
            
            except URLError,e:
                print 'logging error: %s' % str(e)
                """
                Here we have to develop an observer
                class which notifies the error to 
                all clases which are interested in 
                showing it
                (http://en.wikipedia.org/wiki/Observer_pattern#Python)
                """

        else:
            self.urlHandler = handle
        
        self.plainHTML = self.urlHandler.read()
    
    def getDirectLink (self):
        pass
    
    def getWaitingTime(self):
        pass

    def getPlainHTML(self):
        return self.plainHTML



class FormParser (AbstractParser):

    
    def __init__ (self,url=None,premium = False,handle = None):
        AbstractParser.__init__(self,url,premium,handle)
        self.forms = [ ]
        self.currentForm = None
        try:
            self.feed(self.plainHTML)
        except Exception,e:
            #print e
            pass #Ignoring malformed structures
        
    def handle_starttag(self,tag,attrs):
        if tag == 'form':
            action = None
            method = None
            for a in attrs:
                if a[0] == 'action':
                    action = a[1]
                elif a[0] == 'method':
                    method = a[1]
            if action is None:
                print 'logging: malformed form'
                #this error won't be notified to the user
            else:
                self.currentForm = Form(action,method)    

                
        if tag == 'input':
            if self.currentForm is not None:
                type = None
                name = None
                value = None
                for a in attrs:
                    if a[0] == 'type':
                        type = a[1]
                    elif a[0] == 'name':
                        name = a[1]
                    elif a[0] == 'value':
                        value = a[1]
                input = Input(type,value,name)
                self.currentForm.addInput(input)

 #       AbstractParser(self).handle_starttag(tag,attrs)
                
    def handle_endtag(self,tag):
        
        if tag == 'form':

            self.forms.append(self.currentForm)


#        AbstractParser(self).handle_endtag(tag,attrs)

    def getForms(self):
        return self.forms


    def __str__ (self):
        ret = ''
        for f in self.forms:
            ret += '%s\n' % str(f)
        return ret


    def __repr__ (self):
        ret = ''
        for f in self.forms:
            ret += '%s\n' % str(f)
        return ret

class MegaParser(FormParser):
    def __init__ (self,url=None,premium = False,handle = None):
        FormParser.__init__(self,url,premium,handle)

    def saveCaptcha(self,url):
        tmp = urlopen(url);
        fileName = "./captchas/"+ url.rsplit("/")[-1];
        captImage = tmp.read();
        file = open(fileName,"wb");
        file.write(captImage);
        file.close();
        guessCaptcha();
    
    def guessCaptcha(self,fileName):
        pass
    
    def handle_starttag(self,tag,attrs):
        if tag == 'img':
            for a in attrs:
                if a[1].__contains__("gencap.php"):
                    #Getting catcha image
                    self.saveCaptcha(a[1]);

 #       AbstractParser(self).handle_starttag(tag,attrs)
                
    def handle_endtag(self,tag):
        pass
            
class LoginParser(FormParser):
    #Maybe useful in the future

    def __init__(self,user,password,url=None,handle=None):
        FormParser.__init__(self,url,True,handle) 
        self.user = user
        self.password = password

class Form:


    def __init__ (self,action,method,premium=False):
        self.__action = action
        self.__method = method
        self.__inputs = [ ]
        
    def addInput(self,input):
        self.__inputs.append(input)

    def getInputs(self):
        return self.__inputs

    def getAction(self):
        return self.__action

    def __str__(self):
        return 'Form: %s Method: %s, Inputs: %s' % \
            (str(self.__action),str(self.__method), \
            str(self.__inputs))

    def __repr__(self):
        return 'Form: %s Method: %s, Inputs: %s' % \
            (str(self.__action),str(self.__method), \
            str(self.__inputs))


    def request(self):
        """
        Sends the request via post or get
        and returns the response urllib handler
        """
        parmsDic = { }
        handle = None
        for input in self.__inputs:
            if input.name is not None:
                parmsDic[input.name] = input.value
        encodedParameters = urlencode(parmsDic)
        if self.__method == 'post':
            req = Request(self.__action,encodedParameters)
            try:
                cj = LWPCookieJar()
                cj.load(COOKIEFILE)
                opener = build_opener \
                    (HTTPCookieProcessor(cj))
                install_opener(opener)
                handle = opener.open(req)
                cj.save(COOKIEFILE)

            except URLError,e:
                print 'logging error: %s' % str(e)
        elif self.__method == 'get':
            preparedUrl = '%s?%s' % (self.__action,
                                     encodedParameters)
            try:
                cj = LWPCookieJar()
                cj.load(COOKIEFILE)
                opener = build_opener \
                    (HTTPCookieProcessor(cj))
                install_opener(opener)
                handle = opener.open(preparedUrl)
                cj.save(COOKIEFILE)
            except UrlError,e:
                print 'logging error: %s' % str(e)
        return handle
        

        
class Input:


    def __init__(self,type,value,name = None):
        #Value is a public attribute to allow direct access
        self.__type = type
        self.value = value
        self.name = name

    def __str__(self):
        return 'Type: %s Value: %s Name: %s' % (str(self.__type),
                                               str(self.value),
                                               str(self.name))
    
    def __repr__(self):
        return 'Type: %s Value: %s Name: %s' % (str(self.__type),
                                               str(self.value),
                                               str(self.name))

